package cn.net.yugu.doraemon.springweb.interceptor;

import cn.net.yugu.doraemon.springweb.accesslog.AccessLog;
import cn.net.yugu.doraemon.springweb.accesslog.AccessLogHolder;
import cn.net.yugu.doraemon.springweb.config.YgWebProperties;
import cn.net.yugu.doraemon.springweb.constant.YgConstant;
import cn.net.yugu.doraemon.springweb.request.YgHttpRequestWrapper;
import cn.net.yugu.doraemon.springweb.util.IpUtil;
import cn.net.yugu.doraemon.springweb.util.JSONUtil;
import cn.net.yugu.doraemon.springweb.util.ServletUtil;
import cn.net.yugu.doraemon.springweb.util.TraceUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.MDC;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @description:
 * @author: wanghongli
 * @create: 2022-07-28 20:58:40
 */
@Slf4j
@Order(990)
public class YgHttpTraceInterceptor implements HandlerInterceptor {
    private final YgWebProperties ygWebProperties;
    public YgHttpTraceInterceptor(YgWebProperties properties) {
        this.ygWebProperties = properties;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        String traceId = request.getHeader(YgConstant.TRACE_ID);
        if (StringUtils.isBlank(traceId)) {
            traceId = TraceUtil.genTraceId();
        }
        MDC.put(YgConstant.TRACE_ID, traceId);
        MDC.put(YgConstant.HTTP_REQUEST_TIMESTAMP_FLAG, String.valueOf(System.currentTimeMillis()));
        response.addHeader(YgConstant.HTTP_HEADER_TRACE_TAG, traceId);
        String params = "";
        final String contentType = request.getContentType() == null ? "" : request.getContentType();
        if (contentType.contains(MediaType.APPLICATION_JSON_VALUE)) {
            if (HttpMethod.POST.name().equals(request.getMethod()) ) {
                YgHttpRequestWrapper wrapper = new YgHttpRequestWrapper(request);
                params = wrapper.inputStream2String(wrapper.getInputStream());
            } else if (HttpMethod.GET.name().equals(request.getMethod())) {
                params = JSONUtil.toJSONString(request.getParameterMap());
            }
        }

        String requestBody = ServletUtil.getServletInputStream2String(request);
        if (ygWebProperties.isThreadLocalAccessLogEnable()) {
            AccessLog accessLog = AccessLogHolder.get();
            accessLog.setRequestBody(requestBody);
        }

        log.info("request=>url:{} remoteIp:{} method:{} contentType:{} params:{}",
            request.getRequestURI(), IpUtil.getIp(request), request.getMethod(), request.getContentType(), params);
        return true;
    }
}
